package org.smart4j.chapter1.proxy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.chapter1.annotation.Transaction;
import org.smart4j.chapter1.helper.DatabaseHelper;

import java.lang.reflect.Method;

/**
 * @ClassName:
 * @Description: 事务代理
 * @Author: LynnZou
 * @Date: 2017/5/31
 */
public class TransactionProxy implements Proxy {

    private static final Logger LOGGER = LoggerFactory.getLogger(TransactionProxy.class);

    private static final ThreadLocal<Boolean> FLAG_HOLDER = new ThreadLocal<Boolean>(){
        @Override
        protected Boolean initialValue() {
            return false;
        }
    };

    @Override
    public Object doProxy(ProxyChain proxyChian) throws Throwable {

        Object result;

        Boolean flag =FLAG_HOLDER.get();
        Method method = proxyChian.getTargetMethod();
        if(!flag && method.isAnnotationPresent(Transaction.class)){
            FLAG_HOLDER.set(true);
            try{
            DatabaseHelper.beginTransaction();
            LOGGER.debug("begin transaction");
            result = proxyChian.doProxyChain();
            DatabaseHelper.commitTransaction();
            LOGGER.debug("commit transaction");
            }catch (Exception e){
                DatabaseHelper.rollbackTransaction();
                LOGGER.debug("rollback transaction");
                throw e;
            }finally {
                FLAG_HOLDER.remove();
            }
        }else {
            result = proxyChian.doProxyChain();
        }

        return result;
    }
}
